package com.lineage.server.model;

import com.lineage.server.datatables.lock.CastleReading;
import com.lineage.server.serverpackets.S_War;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.templates.L1Castle;
import com.lineage.server.thread.GeneralThreadPool;
import com.lineage.server.world.World;
import com.lineage.server.world.WorldClan;
import com.lineage.server.world.WorldWar;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class L1War {
  private static final Log _log = LogFactory.getLog(L1War.class);
  
  private String _attackClanName = null;
  
  private String _defenceClanName = null;
  
  private L1Clan _defenceClan = null;
  
  private int _warType = 0;
  
  private int _castleId = 0;
  
  private boolean _isWarTimerDelete = false;
  
  private final ConcurrentHashMap<String, L1Clan> _attackList = new ConcurrentHashMap<>();
  
  public int get_castleId() {
    return this._castleId;
  }
  
  public String get_defenceClanName() {
    return this._defenceClanName;
  }
  
  public String get_attackClanName() {
    return this._attackClanName;
  }
  
  public boolean isWarTimerDelete() {
    return this._isWarTimerDelete;
  }
  
  public void handleCommands(int war_type, String attack_clan_name, String defence_clan_name) {
    try {
      SimWarTimer sim_war_timer;
      SimWarTimerPVP sim_war_timerPVP;
      this._attackList.clear();
      this._warType = war_type;
      this._defenceClanName = defence_clan_name;
      this._defenceClan = WorldClan.get().getClan(this._defenceClanName);
      addAttackClan(attack_clan_name);
      declareWar(attack_clan_name, defence_clan_name);
      switch (war_type) {
        case 1:
          this._castleId = getCastleId();
          break;
        case 2:
          sim_war_timer = new SimWarTimer();
          GeneralThreadPool.get().execute(sim_war_timer);
          break;
        case 3:
          sim_war_timerPVP = new SimWarTimerPVP();
          GeneralThreadPool.get().execute(sim_war_timerPVP);
          break;
      } 
      WorldWar.get().addWar(this);
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  private void requestCastleWar(int type, String attack_clan_name) {
    if (attack_clan_name == null)
      return; 
    try {
      L1Clan attack_clan = WorldClan.get().getClan(attack_clan_name);
      if (attack_clan != null && this._defenceClan != null)
        switch (type) {
          case 1:
            World.get().broadcastPacketToAll((ServerBasePacket)new S_War(1, attack_clan_name, this._defenceClanName));
            break;
          case 2:
            World.get().broadcastPacketToAll((ServerBasePacket)new S_War(2, attack_clan_name, this._defenceClanName));
            World.get().broadcastPacketToAll((ServerBasePacket)new S_War(4, this._defenceClanName, attack_clan_name));
            removeAttackClan(attack_clan_name);
            break;
          case 3:
            World.get().broadcastPacketToAll((ServerBasePacket)new S_War(3, attack_clan_name, this._defenceClanName));
            removeAttackClan(attack_clan_name);
            break;
        }  
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  private void requestSimWar(int type, String clan1_name, String clan2_name) {
    try {
      if (clan1_name == null || clan2_name == null)
        return; 
      L1Clan clan1 = WorldClan.get().getClan(clan1_name);
      if (clan1 == null)
        return; 
      L1Clan clan2 = WorldClan.get().getClan(clan2_name);
      if (clan2 == null)
        return; 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
      return;
    } finally {
      switch (type) {
        case 2:
        case 3:
          WorldWar.get().removeWar(this);
          this._isWarTimerDelete = true;
          delete();
          break;
      } 
    } 
    switch (type) {
      case 2:
      case 3:
        WorldWar.get().removeWar(this);
        this._isWarTimerDelete = true;
        delete();
        break;
    } 
  }
  
  public void winCastleWar(String clan_name) {
    try {
      World.get().broadcastPacketToAll((ServerBasePacket)new S_War(4, clan_name, this._defenceClanName));
      Set<String> clanList = getAttackClanList();
      if (!clanList.isEmpty()) {
        Iterator<String> iter = clanList.iterator();
        while (iter.hasNext()) {
          String enemy_clan_name = iter.next();
          World.get().broadcastPacketToAll((ServerBasePacket)new S_War(3, this._defenceClanName, enemy_clan_name));
        } 
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } finally {
      this._isWarTimerDelete = true;
      delete();
      System.out.println(String.valueOf(String.valueOf(clan_name)) + " 王冠夺取,进攻方获胜");
    } 
  }
  
  public void ceaseCastleWar() {
    try {
      Set<String> clanList = getAttackClanList();
      if (!clanList.isEmpty()) {
        Iterator<String> iter = clanList.iterator();
        while (iter.hasNext()) {
          String enemy_clan_name = iter.next();
          World.get().broadcastPacketToAll((ServerBasePacket)new S_War(4, this._defenceClanName, enemy_clan_name));
        } 
        iter = clanList.iterator();
        while (iter.hasNext()) {
          String enemy_clan_name = iter.next();
          World.get().broadcastPacketToAll((ServerBasePacket)new S_War(3, this._defenceClanName, enemy_clan_name));
        } 
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } finally {
      this._isWarTimerDelete = true;
      delete();
      System.out.println(String.valueOf(String.valueOf(this._defenceClanName)) + " 城堡战争时间终止,防御方获胜");
    } 
  }
  
  public void declareWar(String attack_clan_name, String defence_clan_name) {
    try {
      if (getWarType() == 1) {
        requestCastleWar(1, attack_clan_name);
      } else {
        requestSimWar(1, this._attackClanName = attack_clan_name, defence_clan_name);
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public void surrenderWar(String clan1_name, String clan2_name) {
    try {
      if (getWarType() == 1) {
        requestCastleWar(2, clan1_name);
      } else {
        requestSimWar(2, clan1_name, clan2_name);
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public void ceaseWar(String clan1_name, String clan2_name) {
    try {
      if (getWarType() == 1) {
        requestCastleWar(3, clan1_name);
      } else {
        requestSimWar(3, clan1_name, clan2_name);
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public void ceaseWar() {
    try {
      ceaseWar(this._attackClanName, this._defenceClanName);
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public void winWar(String clan1_name, String clan2_name) {
    try {
      if (getWarType() == 1) {
        requestCastleWar(4, clan1_name);
      } else {
        requestSimWar(4, clan1_name, clan2_name);
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public boolean checkClanInWar(String clan_name) {
    if (this._isWarTimerDelete) {
      WorldWar.get().removeWar(this);
      delete();
      return false;
    } 
    boolean ret = false;
    ret = !(!this._defenceClanName.equalsIgnoreCase(clan_name) && !checkAttackClan(clan_name));
    return ret;
  }
  
  public boolean checkClanInSameWar(String player_clan_name, String target_clan_name) {
    boolean player_clan_flag = false;
    boolean target_clan_flag = false;
    player_clan_flag = !(!this._defenceClanName.equalsIgnoreCase(player_clan_name) && 
      !checkAttackClan(player_clan_name));
    target_clan_flag = !(!this._defenceClanName.equalsIgnoreCase(target_clan_name) && 
      !checkAttackClan(target_clan_name));
    return (player_clan_flag && target_clan_flag);
  }
  
  public String getEnemyClanName(String player_clan_name) {
    if (this._defenceClanName.toLowerCase().equals(player_clan_name.toLowerCase())) {
      Set<String> clanList = getAttackClanList();
      if (!clanList.isEmpty()) {
        Iterator<String> iter = clanList.iterator();
        if (iter.hasNext())
          return iter.next(); 
      } 
      return null;
    } 
    return this._defenceClanName;
  }
  
  public void delete() {
    try {
      this._attackList.clear();
      WorldWar.get().removeWar(this);
      _log.info(
          String.valueOf(String.valueOf(this._defenceClanName)) + " 战争终止完成 剩余战争清单数量:" + WorldWar.get().getWarList().size());
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public int getWarType() {
    return this._warType;
  }
  
  public void addAttackClan(String attack_clan_name) {
    L1Clan attack_clan = WorldClan.get().getClan(attack_clan_name);
    if (attack_clan != null)
      this._attackList.put(attack_clan_name.toLowerCase(), attack_clan); 
  }
  
  public void removeAttackClan(String attack_clan_name) {
    if (this._attackList.get(attack_clan_name.toLowerCase()) != null)
      this._attackList.remove(attack_clan_name.toLowerCase()); 
  }
  
  public boolean checkAttackClan(String attack_clan_name) {
    return (this._attackList.get(attack_clan_name.toLowerCase()) != null);
  }
  
  public Set<String> getAttackClanList() {
    return this._attackList.keySet();
  }
  
  public int getCastleId() {
    L1Clan clan;
    switch (this._warType) {
      case 1:
        clan = WorldClan.get().getClan(this._defenceClanName);
        if (clan != null) {
          int castle_id = clan.getCastleId();
          return castle_id;
        } 
        break;
    } 
    return 0;
  }
  
  public L1Castle getCastle() {
    L1Clan clan;
    switch (this._warType) {
      case 1:
        clan = WorldClan.get().getClan(this._defenceClanName);
        if (clan != null) {
          int castle_id = clan.getCastleId();
          L1Castle castle = CastleReading.get().getCastleTable(castle_id);
          return castle;
        } 
        break;
    } 
    return null;
  }
  
  class SimWarTimer implements Runnable {
    public void run() {
      int loop = 0;
      while (loop < 240) {
        try {
          Thread.sleep(60000L);
        } catch (Exception exception) {
          break;
        } 
        if (L1War.this._isWarTimerDelete)
          return; 
        loop++;
      } 
      WorldWar.get().removeWar(L1War.this);
      L1War.this.ceaseWar(L1War.this._attackClanName, L1War.this._defenceClanName);
      L1War.this.delete();
    }
  }
  
  class SimWarTimerPVP implements Runnable {
    public void run() {
      int loop = 0;
      while (loop < 20) {
        try {
          Thread.sleep(60000L);
        } catch (Exception exception) {
          break;
        } 
        if (L1War.this._isWarTimerDelete)
          return; 
        loop++;
      } 
      L1War.this.ceaseWar(L1War.this._attackClanName, L1War.this._defenceClanName);
      L1War.this.delete();
    }
  }
}
